package org.whp.mealplanner.server;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import javax.jdo.PersistenceManager;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import javax.jdo.Query;

import net.sf.jsr107cache.Cache;
import net.sf.jsr107cache.CacheException;
import net.sf.jsr107cache.CacheFactory;
import net.sf.jsr107cache.CacheManager;

public class IngredientsAjaxServlet extends HttpServlet {

	Cache cache;
	List<Ingredient> ingredients;
	
	protected Cache getMemCache() {
      
		if (cache==null) {
			try {
				CacheFactory cacheFactory = CacheManager.getInstance()
						.getCacheFactory();
				cache = cacheFactory.createCache(Collections.emptyMap());
				CacheManager.getInstance().registerCache("ingredients", cache);
			} catch (CacheException e) {

			}
		} else {
			cache = CacheManager.getInstance().getCache("ingredients");
		}
		return cache;
	}
	
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		
		cache = getMemCache();
		
		ingredients = new ArrayList<Ingredient>();
		int startIdx = Integer.valueOf(req.getParameter("startIdx"));
		int endIdx = Integer.valueOf(req.getParameter("endIdx"));
		int ingredientAddedIndicator = 0;
		if (req.getParameter("ingadd") != null) {
			ingredientAddedIndicator = Integer.valueOf(req
					.getParameter("ingadd"));
		}
		if (!cache.containsKey(endIdx-1) | ingredientAddedIndicator == 1){
			PersistenceManager pm = PMF.get().getPersistenceManager();
			String queryString = "select from " + Ingredient.class.getName()
					+ " order by name asc";
			Query query = pm.newQuery(queryString);
			query.setRange((long) startIdx, (long) endIdx);
			ingredients = (List<Ingredient>) query.execute();
			Iterator<Ingredient> ingredientsIterator = ingredients.iterator();
			for (int i = startIdx; i < endIdx; i++) {
				if (ingredientsIterator.hasNext()){
				Ingredient ingredientForCache = (Ingredient)ingredientsIterator.next();
				byte[] ingredientForCacheByteArray = ingredientForCache.serialize();
				cache.put(i, ingredientForCacheByteArray);
				}
				else {
				}
			}
		} else {
			for (int i = startIdx; i < endIdx; i++) {				
				byte[] ingredientByteArrayFromCache = (byte[]) cache.get(i);
				if (ingredientByteArrayFromCache != null) {
					ByteArrayInputStream bis = new ByteArrayInputStream(
							ingredientByteArrayFromCache);
					ObjectInputStream ois = new ObjectInputStream(bis);
					Ingredient ingredientFromCache = null;
					try {
						ingredientFromCache = (Ingredient) ois.readObject();
						ingredients.add(ingredientFromCache);
					} catch (ClassNotFoundException e) {
						e.printStackTrace();
					}
				}
			}
		}
	
		

		if (!ingredients.isEmpty()) {
			StringBuilder sb = new StringBuilder();
			for (Ingredient ingredient : ingredients) {
				sb.append("<tr><td>");
				sb.append(ingredient.getName());
				sb.append("</td>");
				sb.append("<td>");
				sb.append("<input type=\"checkbox\" name=\"");
				sb.append(ingredient.getEncodedKey());
				sb.append("\" />");
				sb.append("</td></tr>");
			}

/*			List<String> ingredientsNamesFromCache = new ArrayList<String>();
			for (int i = startIdx; i < endIdx; i++) {
				
				byte[] ingredientByteArrayFromCache = (byte[]) cache.get(i);
				if (ingredientByteArrayFromCache != null) {
					ByteArrayInputStream bis = new ByteArrayInputStream(
							ingredientByteArrayFromCache);
					ObjectInputStream ois = new ObjectInputStream(bis);
					Ingredient ingredientFromCache = null;
					try {
						ingredientFromCache = (Ingredient) ois.readObject();
					} catch (ClassNotFoundException e) {
						e.printStackTrace();
					}
					if (ingredientFromCache != null) {
						ingredientsNamesFromCache.add(ingredientFromCache
								.getName());
					}else {
						i = endIdx;
					}
				}
			}
			
			
			for (String ingredientName: ingredientsNamesFromCache) {
				sb.append("<tr><td>");
				sb.append(ingredientName);
				sb.append("</td></tr>");
			}*/
			resp.setContentType("text/plain");
			resp.setHeader("Cache-Control", "no-cache");
			resp.getWriter().write(sb.toString());
		} else {
			resp.setContentType("text/plain");
			resp.setHeader("Cache-Control", "no-cache");
			resp.getWriter()
					.write("<tr><td>&nbsp;</td></tr>"
							+ "<tr><td>&nbsp;</td></tr>"
							+ "<tr><td>&nbsp;</td></tr>"
							+ "<tr><td>&nbsp;</td></tr>"
							+ "<tr><td>There are not any ingredients yet.</td></tr>");
		}

	}

}
